package com.example.qxfw.nyqx.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.example.qxfw.common.entity.zy.AgriProduct;
import com.example.qxfw.common.util.DateUtil;
import com.example.qxfw.common.util.DocxUtil;
import com.example.qxfw.mongodb.hy.entity.HyDocFile;
import com.example.qxfw.mongodb.hy.service.DocFileService;
import com.example.qxfw.mongodb.hy.service.PdfFileService;
import com.example.qxfw.nyqx.mapper.AgriProductMapper;
import com.example.qxfw.nyqx.service.AgriProductService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class AgriProductServiceImpl implements AgriProductService {

    @Value("${filePath.docFilePath}")
    private String docFilePath;
    @Value("${filePath.pdfFilePath}")
    private String pdfFilePath;
    @Value("${filePath.ip}")
    private String ip;
    @Value("${filePath.port}")
    private String port;
    @Autowired
    private AgriProductMapper agriProductMapper;
    @Autowired
    private DocFileService docFileService;

    @Autowired
    private PdfFileService pdfFileService;

    @Override
    public List<AgriProduct> listByParam(String productType, String time1, String time2, String name) {
        return agriProductMapper.selectList(Wrappers.<AgriProduct>lambdaQuery()
                .eq(StringUtils.isNotBlank(productType), AgriProduct::getProducttype, productType)
                .between(StringUtils.isNotBlank(time1), AgriProduct::getForecasttime, Timestamp.valueOf(time1), Timestamp.valueOf(time2))
                .like(StringUtils.isNotBlank(name), AgriProduct::getProductname, name)
                .orderByDesc(AgriProduct::getForecasttime));
    }

    @Override
    public List<AgriProduct> listByParam1(String time1, String time2, String productType) {
        return agriProductMapper.selectList(Wrappers.<AgriProduct>lambdaQuery()
                .eq(StringUtils.isNotBlank(productType), AgriProduct::getProducttype, productType)
                .between(StringUtils.isNotBlank(time1), AgriProduct::getForecasttime, Timestamp.valueOf(time1), Timestamp.valueOf(time2))
                .orderByDesc(AgriProduct::getForecasttime));
    }

    @Override
    public List<AgriProduct> listByParam2(String productName, String productType) {
        return agriProductMapper.selectList(Wrappers.<AgriProduct>lambdaQuery()
                .eq(StringUtils.isNotBlank(productType), AgriProduct::getProducttype, productType)
                .eq(StringUtils.isNotBlank(productName), AgriProduct::getProductname, productName)
        );
    }

    @Override
    public List<AgriProduct> listByParam3(String productType, String time1, String time2, String smalltype, String name) {
        return agriProductMapper.selectList(Wrappers.<AgriProduct>lambdaQuery()
                .eq(StringUtils.isNotBlank(productType), AgriProduct::getProducttype, productType)
                .between(StringUtils.isNotBlank(time1), AgriProduct::getForecasttime, Timestamp.valueOf(time1), Timestamp.valueOf(time2))
                .like(StringUtils.isNotBlank(name), AgriProduct::getProductname, name)
                .like(StringUtils.isNotBlank(smalltype), AgriProduct::getProductname, smalltype)
                .orderByDesc(AgriProduct::getForecasttime));
    }

    @Override
    public AgriProduct saveProduct(AgriProduct agriProduct) {
        agriProductMapper.insert(agriProduct);
        return agriProduct;
    }

    @Override
    public Integer deleteById(String id) {
        return agriProductMapper.deleteById(id);
    }

    @Override
    public Integer update(AgriProduct agriProduct) {
        return agriProductMapper.updateById(agriProduct);
    }


    /**
     * 农用天气预报的所有文档生成功能都是用该接口
     *
     * @param phase      期数：需要的格式为： String2023年001期
     * @param admin      签发人
     * @param title      标题（这里有三种类型：传递的参数请给012，0代表周农用气象预报，1代表月农用气象预报，2代表农业气象灾害预警）
     * @param tendencies 天气趋势
     * @param advice     提示与建议
     * @param tel        电话
     * @return url 网址
     */
    @Override
    public String agriculturalWeatherForecast(String phase, String admin, String title, String tendencies, String advice, String tel, HttpServletResponse response) throws IOException {
        String url = "";
        // 判断预报的类型
        if (title.equals("0")) {
            title = "周农用气象预报";
        } else if (title.equals("1")) {
            title = "月农用气象预报";
        } else if (title.equals("2")) {
            title = "农业气象灾害预警";
        }
        // maketime
        Timestamp timestampMake = DateUtil.localDateTimeToTimestamp(LocalDateTime.now());
        // forecasttime
        LocalDate currentDate = LocalDate.now();
        Timestamp timestampForcast = DateUtil.localDateTimeToTimestamp(currentDate.atStartOfDay());
        // 先获取表中是否已经又生成好的数据，有就直接查询将查询的结果返回，无则生成。
        AgriProduct product = agriProductMapper.selectOne(new LambdaQueryWrapper<AgriProduct>()
                .eq(AgriProduct::getProducttype, title)
                .eq(AgriProduct::getForecasttime, timestampForcast)
                .eq(AgriProduct::getProductname, "玉林-气象服务信息-" + phase.replace("年", "").replace("期", "") + "-" + title + ".docx"));
        if (product != null) {
            // 获取mongo库里的文档
            HyDocFile hyDocFile = docFileService.getByTableId(String.valueOf(product.getId()));
            // 如果文档存在就直接返回查询结果
            if (hyDocFile != null) {
                try (InputStream inputStream = new ByteArrayInputStream(hyDocFile.getData());
                     ServletOutputStream outputStream = response.getOutputStream()) {
                    response.setContentType("application/octet-stream");
                    response.addHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode("doc_File", "UTF-8"));
                    byte[] b = new byte[1024];
                    int len;
                    while ((len = inputStream.read(b)) > 0) {
                        outputStream.write(b, 0, len);
                    }
                    url = "完成";
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return url;
            } else {
                // 如果表中有信息，文档不存在或表中无信息，就新生成一个文档并删除这条数据
                int i = agriProductMapper.deleteById(product.getId());
                log.warn("删除了表agri_product中的" + i + "条数据");
                // 文档信息，先存入表agri_product
                AgriProduct agriProduct = new AgriProduct();
                agriProduct.setProductname("玉林-气象服务信息-" + phase.replace("年", "").replace("期", "") + "-" + title + ".docx");
                agriProduct.setProducttype(title);
                agriProduct.setForecasttime(timestampForcast);
                agriProduct.setMaketime(timestampMake);
                agriProduct.setMaker(admin);
                agriProduct.setState("0");
                agriProduct.setShflag(null);
                agriProduct.setShidea(null);
                int insert = agriProductMapper.insert(agriProduct);
                // 数据插入后，再执行文档的生成
                if (insert > 0) {
                    String sourcePath;
                    // 判断使用哪个模板
                    sourcePath = title.equals("0") || title.equals("2") ? "templates/nytqTemp/农用天气预报.docx" : "templates/nytqTemp/农用月天气预报.docx";
                    String targetPath = docFilePath + agriProduct.getProductname();
                    String[] placeholders = new String[]{"[期数]", "[签发人]", "[标题]", "[天气趋势]", " [提示与建议]", "[联系电话]", "[年月日时]"};

                    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日HH时");
                    String formattedDate = dateFormat.format(new Date(timestampMake.getTime()));

                    String[] replacements = new String[]{phase, admin, title, tendencies, advice, tel, formattedDate};
                    // 文档生成
                    DocxUtil.generateWordDocx(sourcePath, targetPath, placeholders, replacements);
                    // 将生成的文档保存入mg数据库
                    File docxFile = new File(targetPath);
                    // 判断文档是否已经生成完毕
                    if (docxFile.exists()) {
                        //文件保存入数据库
                        HyDocFile file = new HyDocFile();
                        try {
                            byte[] bytes = DocxUtil.readDocxFileToByteArray(targetPath);
                            file.setData(bytes);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        file.setId(String.valueOf(agriProduct.getId()));
                        file.setTable_name("agri_product");
                        file.setName(agriProduct.getProducttype() + ".docx");
                        docFileService.save(file);
                        //生成pdf文档并返回url
                        String name = agriProduct.getProductname().replace(".docx", "") + ".pdf";
                        String pdfPath = pdfFilePath + name;
                        System.err.println("pdfPath:" + pdfPath);
                        DocxUtil.wordToPdf(targetPath, pdfPath);
                        url = "http://" + ip + ":" + port + "/static/" + name;
                    } else {
                        // 文件生成失败，可以抛出异常或者执行其他处理逻辑
                        throw new RuntimeException("生成docx文件失败！");
                    }
                }
                return url;
            }
        } else {
            // 文档信息，先存入表agri_product
            AgriProduct agriProduct = new AgriProduct();
            agriProduct.setProductname("玉林-气象服务信息-" + phase.replace("年", "").replace("期", "") + "-" + title + ".docx");
            agriProduct.setProducttype(title);
            agriProduct.setForecasttime(timestampForcast);
            agriProduct.setMaketime(timestampMake);
            agriProduct.setMaker(admin);
            agriProduct.setState("0");
            agriProduct.setShflag(null);
            agriProduct.setShidea(null);
            int insert = agriProductMapper.insert(agriProduct);
            // 数据插入后，再执行文档的生成
            if (insert > 0) {
                String sourcePath;
                // 判断使用哪个模板
                sourcePath = title.equals("0") || title.equals("2") ? "templates/nytqTemp/农用天气预报.docx" : "templates/nytqTemp/农用月天气预报.docx";
                String targetPath = docFilePath + agriProduct.getProductname();
                String[] placeholders = new String[]{"[期数]", "[签发人]", "[标题]", "[天气趋势]", " [提示与建议]", "[联系电话]", "[年月日时]"};

                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日HH时");
                String formattedDate = dateFormat.format(new Date(timestampMake.getTime()));

                String[] replacements = new String[]{phase, admin, title, tendencies, advice, tel, formattedDate};
                // 文档生成
                DocxUtil.generateWordDocx(sourcePath, targetPath, placeholders, replacements);
                // 将生成的文档保存入mg数据库
                File docxFile = new File(targetPath);
                // 判断文档是否已经生成完毕
                if (docxFile.exists()) {
                    //文件保存入数据库
                    HyDocFile file = new HyDocFile();
                    try {
                        byte[] bytes = DocxUtil.readDocxFileToByteArray(targetPath);
                        file.setData(bytes);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    file.setId(String.valueOf(agriProduct.getId()));
                    file.setTable_name("agri_product");
                    file.setName(agriProduct.getProducttype() + ".docx");
                    docFileService.save(file);
                    //生成pdf文档并返回url
                    String name = agriProduct.getProductname().replace(".docx", "") + ".pdf";
                    String pdfPath = pdfFilePath + name;
                    DocxUtil.wordToPdf(targetPath, pdfPath);
                    url = "http://" + ip + ":" + port + "/static/" + name;
                } else {
                    // 文件生成失败，可以抛出异常或者执行其他处理逻辑
                    throw new RuntimeException("生成docx文件失败！");
                }
            }
        }
        return url;
    }

    @Override
    public String developmentalForecasting(String cropName, String stationName, String growDateName, String type, String dateTime, String date, String d, String d1, String a, String b, String t, HttpServletResponse response) throws IOException {
        String url = "";
        // 先去农业产品表中获取获取数据
        String[] s = dateTime.split(" ");
        AgriProduct agriProduct = agriProductMapper.selectOne(new LambdaQueryWrapper<AgriProduct>()
                .eq(AgriProduct::getProductname, s[0] + cropName + "发育期预报.docx")
                .eq(AgriProduct::getProducttype, "发育期预报")
                .eq(AgriProduct::getForecasttime, DateUtil.localDateTimeToTimestamp(DateUtil.stringToLocalDateTime(dateTime))));
        // 如果获取到了数据就直接将数据库的数据进行查询并返回
        if (agriProduct != null) {
            // 获取mongo库里的文档
            HyDocFile hyDocFile = docFileService.getByTableId(String.valueOf(agriProduct.getId()));
            // 如果文档存在就直接返回查询结果
            if (hyDocFile != null) {
                try (InputStream inputStream = new ByteArrayInputStream(hyDocFile.getData());
                     ServletOutputStream outputStream = response.getOutputStream()) {
                    response.setContentType("application/octet-stream");
                    response.addHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode("doc_File", "UTF-8"));
                    byte[] bytes = new byte[1024];
                    int len;
                    while ((len = inputStream.read(bytes)) > 0) {
                        outputStream.write(bytes, 0, len);
                    }
                    url = "完成";
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return url;
                // 如果数据库查到了但是，文档不存在，就删除数据库的信息，然后重新生成数据和文档
            } else {
                // 如果表中有信息，文档不存在或表中无信息，就新生成一个文档并删除这条数据
                int i = agriProductMapper.deleteById(agriProduct.getId());
                log.warn("删除了表agri_product中的" + i + "条数据");
                // 文档信息，先存入表agri_product
                // 文档信息，先存入表agri_product
                AgriProduct product = new AgriProduct();
                product.setProductname(s[0] + cropName + "发育期预报.docx");
                product.setProducttype("发育期预报");
                product.setForecasttime(DateUtil.localDateTimeToDate(DateUtil.stringToLocalDateTime(dateTime)));
                Timestamp timestamp = DateUtil.localDateTimeToTimestamp(LocalDateTime.now());
                product.setMaketime(timestamp);
                product.setMaker("admin");
                product.setState("0");
                int insert = agriProductMapper.insert(product);
                // 数据插入后，再执行文档的生成
                if (insert > 0) {
                    // 选择使用的模板
                    String sourcePath = "templates/nqfwTemp/发育期预报.docx";
                    String targetPath = docFilePath + product.getProductname();
                    String[] placeholders = new String[]{"【1】年【2】月【3】日", "【4】", "【5】", "【6】", "【7】", "【8】", "【9】", "【10】", "【11】", "【12】", "【13】"};
                    String[] replacements = new String[placeholders.length];

                    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日HH时");
                    String formattedDate = dateFormat.format(timestamp.getTime());
                    replacements[0] = formattedDate;
                    replacements[1] = d;
                    replacements[2] = d1;
                    replacements[3] = a;
                    replacements[4] = b;
                    replacements[5] = t;
                    replacements[6] = stationName;
                    replacements[7] = growDateName;
                    replacements[8] = date;
                    replacements[9] = type;
                    replacements[10] = cropName;
                    // 文档生成
                    DocxUtil.generateWordDocx(sourcePath, targetPath, placeholders, replacements);
                    // 将生成的文档保存入mg数据库
                    File docxFile = new File(targetPath);
                    // 判断文档是否已经生成完毕
                    if (docxFile.exists()) {
                        //文件保存入数据库
                        HyDocFile file = new HyDocFile();
                        try {
                            byte[] bytes = DocxUtil.readDocxFileToByteArray(targetPath);
                            file.setData(bytes);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        file.setId(String.valueOf(agriProduct.getId()));
                        file.setTable_name("agri_product");
                        file.setName(agriProduct.getProducttype() + ".docx");
                        docFileService.save(file);
                        //生成pdf文档并返回url
                        String name = agriProduct.getProductname().replace(".docx", "") + ".pdf";
                        String pdfPath = pdfFilePath + name;
                        DocxUtil.wordToPdf(targetPath, pdfPath);
                        url = "http://" + ip + ":" + port + "/static/" + name;
                    } else {
                        // 文件生成失败，可以抛出异常或者执行其他处理逻辑
                        throw new RuntimeException("生成docx文件失败！");
                    }
                }
                return url;
            }
            // 如果没有在数据库中查到数据，就生成一条数据
        } else {
            // 文档信息，先存入表agri_product
            AgriProduct product = new AgriProduct();
            product.setProductname(s[0] + cropName + "发育期预报.docx");
            product.setProducttype("发育期预报");
            product.setForecasttime(DateUtil.localDateTimeToDate(DateUtil.stringToLocalDateTime(dateTime)));
            Timestamp timestamp = DateUtil.localDateTimeToTimestamp(LocalDateTime.now());
            product.setMaketime(timestamp);
            product.setMaker("admin");
            product.setState("0");
            product.setShflag(null);
            product.setShidea(null);
            int insert = agriProductMapper.insert(product);
            // 数据插入后，再执行文档的生成
            if (insert > 0) {
                // 选择使用的模板
                String sourcePath = "templates/nqfwTemp/发育期预报.docx";
                String targetPath = docFilePath + product.getProductname();
                String[] placeholders = new String[]{"【1】年【2】月【3】日", "【4】", "【5】", "【6】", "【7】", "【8】", "【9】", "【10】", "【11】", "【12】", "【13】"};
                String[] replacements = new String[placeholders.length];

                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日HH时");
                String formattedDate = dateFormat.format(timestamp.getTime());
                replacements[0] = formattedDate;
                replacements[1] = d;
                replacements[2] = d1;
                replacements[3] = a;
                replacements[4] = b;
                replacements[5] = t;
                replacements[6] = stationName;
                replacements[7] = growDateName;
                replacements[8] = date;
                replacements[9] = type;
                replacements[10] = cropName;
                // 文档生成
                DocxUtil.generateWordDocx(sourcePath, targetPath, placeholders, replacements);
                // 将生成的文档保存入mg数据库
                File docxFile = new File(targetPath);
                // 判断文档是否已经生成完毕
                if (docxFile.exists()) {
                    //文件保存入数据库
                    HyDocFile file = new HyDocFile();
                    try {
                        byte[] bytes = DocxUtil.readDocxFileToByteArray(targetPath);
                        file.setData(bytes);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    file.setId(String.valueOf(agriProduct.getId()));
                    file.setTable_name("agri_product");
                    file.setName(agriProduct.getProducttype() + ".docx");
                    docFileService.save(file);
                    //生成pdf文档并返回url
                    String name = agriProduct.getProductname().replace(".docx", "") + ".pdf";
                    String pdfPath = pdfFilePath + name;
                    DocxUtil.wordToPdf(targetPath, pdfPath);
                    url = "http://" + ip + ":" + port + "/static/" + name;
                } else {
                    // 文件生成失败，可以抛出异常或者执行其他处理逻辑
                    throw new RuntimeException("生成docx文件失败！");
                }
            }
        }
        return url;
    }

    @Override
    public Integer queryId(String productName, final String productType, final Timestamp forecastTime, final Timestamp makeTime, final String maker) {
        return agriProductMapper.selectId(productName, productType, forecastTime, makeTime,maker);
    }

    @Override
    public HyDocFile getDocById(String id) {
        HyDocFile hyDocFile = docFileService.getByTableId(id);
        return hyDocFile;
    }
}
